package org.jarraiders.musiclibrary.client;

import org.jarraiders.musiclibrary.client.event.AddAlbumEvent;
import org.jarraiders.musiclibrary.client.event.AddAlbumEventHandler;
import org.jarraiders.musiclibrary.client.event.AddArtistEvent;
import org.jarraiders.musiclibrary.client.event.AddArtistEventHandler;
import org.jarraiders.musiclibrary.client.event.AddTrackEvent;
import org.jarraiders.musiclibrary.client.event.AddTrackEventHandler;
import org.jarraiders.musiclibrary.client.event.AlbumUpdatedEvent;
import org.jarraiders.musiclibrary.client.event.AlbumUpdatedEventHandler;
import org.jarraiders.musiclibrary.client.event.ArtistUpdatedEvent;
import org.jarraiders.musiclibrary.client.event.ArtistUpdatedEventHandler;
import org.jarraiders.musiclibrary.client.event.EditAlbumCancelledEvent;
import org.jarraiders.musiclibrary.client.event.EditAlbumCancelledEventHandler;
import org.jarraiders.musiclibrary.client.event.EditAlbumEvent;
import org.jarraiders.musiclibrary.client.event.EditAlbumEventHandler;
import org.jarraiders.musiclibrary.client.event.EditArtistCancelledEvent;
import org.jarraiders.musiclibrary.client.event.EditArtistCancelledEventHandler;
import org.jarraiders.musiclibrary.client.event.EditArtistEvent;
import org.jarraiders.musiclibrary.client.event.EditArtistEventHandler;
import org.jarraiders.musiclibrary.client.event.EditTrackCancelledEvent;
import org.jarraiders.musiclibrary.client.event.EditTrackCancelledEventHandler;
import org.jarraiders.musiclibrary.client.event.EditTrackEvent;
import org.jarraiders.musiclibrary.client.event.EditTrackEventHandler;
import org.jarraiders.musiclibrary.client.event.TrackUpdatedEvent;
import org.jarraiders.musiclibrary.client.event.TrackUpdatedEventHandler;
import org.jarraiders.musiclibrary.client.layout.Layout;
import org.jarraiders.musiclibrary.client.presenter.AlbumsPresenter;
import org.jarraiders.musiclibrary.client.presenter.ArtistsPresenter;
import org.jarraiders.musiclibrary.client.presenter.EditAlbumPresenter;
import org.jarraiders.musiclibrary.client.presenter.EditArtistPresenter;
import org.jarraiders.musiclibrary.client.presenter.EditTrackPresenter;
import org.jarraiders.musiclibrary.client.presenter.Presenter;
import org.jarraiders.musiclibrary.client.presenter.TracksPresenter;
import org.jarraiders.musiclibrary.client.view.AlbumsView;
import org.jarraiders.musiclibrary.client.view.ArtistsView;
import org.jarraiders.musiclibrary.client.view.EditAlbumView;
import org.jarraiders.musiclibrary.client.view.EditArtistView;
import org.jarraiders.musiclibrary.client.view.EditTrackView;
import org.jarraiders.musiclibrary.client.view.LeftPanel;
import org.jarraiders.musiclibrary.client.view.TracksView;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.HasWidgets;

public class AppController implements Presenter, ValueChangeHandler<String> {
	private final HandlerManager eventBus;
	
	private final ArtistsServiceAsync artistsRpcService;
	private final AlbumsServiceAsync albumsRpcService;
	private final TracksServiceAsync tracksRpcService;
	private HasWidgets container;
	private LeftPanel leftpanel;

	public AppController( ArtistsServiceAsync artistsRpcService,
			AlbumsServiceAsync albumsRpcService, TracksServiceAsync tracksRpcService, HandlerManager eventBus, Layout mainLayout) {
		this.eventBus = eventBus;
		
		this.artistsRpcService = artistsRpcService;
		this.albumsRpcService = albumsRpcService;
		this.tracksRpcService = tracksRpcService;
		this.leftpanel=mainLayout.getLeftPanel();
		bind();
	}

	private void bind() {
		History.addValueChangeHandler(this);

		
		eventBus.addHandler(AddArtistEvent.TYPE, new AddArtistEventHandler() {
			public void onAddArtist(AddArtistEvent event) {
				doAddNewArtist();
			}			
		});

		eventBus.addHandler(EditArtistEvent.TYPE, new EditArtistEventHandler() {
			public void onEditArtist(EditArtistEvent event) {
				doEditArtist(event.getId());
			}
		});

		eventBus.addHandler(EditArtistCancelledEvent.TYPE, new EditArtistCancelledEventHandler() {
			public void onEditArtistCancelled(EditArtistCancelledEvent event) {
				doEditArtistCancelled();
			}
		});

		eventBus.addHandler(ArtistUpdatedEvent.TYPE, new ArtistUpdatedEventHandler() {
			public void onArtistUpdated(ArtistUpdatedEvent event) {
				doArtistUpdated();
			}
		});
		eventBus.addHandler(AddAlbumEvent.TYPE, new AddAlbumEventHandler() {
			public void onAddAlbum(AddAlbumEvent event) {
				doAddNewAlbum();
			}
		});

		eventBus.addHandler(EditAlbumEvent.TYPE, new EditAlbumEventHandler() {
			public void onEditAlbum(EditAlbumEvent event) {
				doEditAlbum(event.getId());
			}
		});

		eventBus.addHandler(EditAlbumCancelledEvent.TYPE, new EditAlbumCancelledEventHandler() {
			public void onEditAlbumCancelled(EditAlbumCancelledEvent event) {
				doEditAlbumCancelled();
			}
		});

		eventBus.addHandler(AlbumUpdatedEvent.TYPE, new AlbumUpdatedEventHandler() {
			public void onAlbumUpdated(AlbumUpdatedEvent event) {
				doAlbumUpdated();
			}
		});
		eventBus.addHandler(AddTrackEvent.TYPE, new AddTrackEventHandler() {
			public void onAddTrack(AddTrackEvent event) {
				doAddNewTrack();
			}
		});

		eventBus.addHandler(EditTrackEvent.TYPE, new EditTrackEventHandler() {
			public void onEditTrack(EditTrackEvent event) {
				doEditTrack(event.getId());
			}
		});

		eventBus.addHandler(EditTrackCancelledEvent.TYPE, new EditTrackCancelledEventHandler() {
			public void onEditTrackCancelled(EditTrackCancelledEvent event) {
				doEditTrackCancelled();
			}
		});

		eventBus.addHandler(TrackUpdatedEvent.TYPE, new TrackUpdatedEventHandler() {
			public void onTrackUpdated(TrackUpdatedEvent event) {
				doTrackUpdated();
			}
		});
	}

	protected void doTrackUpdated() {
		History.newItem("list_track");
		
	}

	protected void doEditTrackCancelled() {
		History.newItem("list_track");
		
	}

	protected void doEditTrack(String id) {
		History.newItem("edit_track", false);
		Presenter presenter = new EditTrackPresenter(tracksRpcService, eventBus, new EditTrackView(), id);
		presenter.go(container);
		
	}

	protected void doAddNewTrack() {
		History.newItem("add_track");
		
	}

	protected void doAlbumUpdated() {
		History.newItem("list_album");
		
	}

	protected void doEditAlbumCancelled() {
		History.newItem("list_album");
		
	}

	protected void doEditAlbum(String id) {
		History.newItem("edit", false);
		Presenter presenter = new EditAlbumPresenter(albumsRpcService, eventBus, new EditAlbumView(), id);
		presenter.go(container);
		
	}

	protected void doAddNewAlbum() {
		History.newItem("add_album");
		
	}

	protected void doArtistUpdated() {
		History.newItem("list_artist");
		
	}

	protected void doEditArtistCancelled() {
		History.newItem("list_artist");
		
	}

	protected void doEditArtist(String id) {
		History.newItem("edit", false);
		Presenter presenter = new EditArtistPresenter(artistsRpcService, eventBus, new EditArtistView(), id);
		presenter.go(container);
		
	}

	protected void doAddNewArtist() {
		History.newItem("add_artist");
		
	}

	public void go(final HasWidgets container) {
		this.container = container;

		if ("".equals(History.getToken())) {
			History.newItem("list_artist");
		} else {
			History.fireCurrentHistoryState();
		}
	}
	
	@Override
	public void onValueChange(ValueChangeEvent<String> event) {
		String token = event.getValue();

		if (token != null) {
			Presenter presenter = null;
			

			if (token.equals("list_artist")) {
				ArtistsView artistView=new ArtistsView();
				presenter = new ArtistsPresenter(artistsRpcService, eventBus, artistView);
				artistView.setPresenter((ArtistsPresenter)presenter);
				leftpanel.getSelectedItem();
			} else if (token.equals("edit_artist")) {
				presenter = new EditArtistPresenter(artistsRpcService, eventBus, new EditArtistView());
			}else if (token.equals("add_artist")) {
				presenter = new EditArtistPresenter(artistsRpcService, eventBus, new EditArtistView());
			} else if (token.equals("list_album")) {
				presenter = new AlbumsPresenter(albumsRpcService, eventBus, new AlbumsView());
				leftpanel.getSelectedItem();
			}else if (token.equals("add_album")) {
				presenter = new EditAlbumPresenter(albumsRpcService, eventBus, new EditAlbumView());
			} else if (token.equals("edit_album")) {
				presenter = new EditAlbumPresenter(albumsRpcService, eventBus, new EditAlbumView());
			}else if (token.equals("list_track")) {
				presenter = new TracksPresenter(tracksRpcService, eventBus, new TracksView());
				leftpanel.getSelectedItem();
			} else if (token.equals("edit_track")) {
				presenter = new EditTrackPresenter(tracksRpcService, eventBus, new EditTrackView());
			}else if (token.equals("add_track")) {
				presenter = new EditTrackPresenter(tracksRpcService, eventBus, new EditTrackView());
			} 
			if (presenter != null) {
				presenter.go(container);
			}
		}
	}
}
